package com.one.rope.mvp.basecore.util;

import org.apache.commons.text.RandomStringGenerator;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author Weijian.liu
 * @desc 随机工具类
 * @date 2018/12/5
 */
public class RandomUtis {

  /**
   * 随机产生min到max之间的一个整数值，包含min和max
   */
  public static int random(int min, int max) {
    if (min > max) {
      throw new IllegalArgumentException("传入的范围不合法!最小值不能大于最大值！");
    }

    return ThreadLocalRandom.current().nextInt(max - min + 1) + min;
  }

  /**
   * 随机产生min到max之间的一个整数值，包含min,但不包含max
   */
  public static int randomExcludeMax(int min, int max) {
    if (min > max) {
      throw new IllegalArgumentException("传入的范围不合法!最小值不能大于最大值！");
    }

    return ThreadLocalRandom.current().nextInt(max - min) + min;
  }


  /**
   * 根据几率计算是否生成，成功几率是sucRange/maxRange
   *
   * @param maxRange 最大范围，随机范围是[1,maxRange]
   * @param sucRange 成功范围，成功范围是[1,sucRange]
   * @return 成功true失败false
   */
  public static boolean isGenerate(int maxRange, int sucRange) {
    return maxRange == sucRange || sucRange != 0 && random(1, maxRange) <= sucRange;
  }

  /**
   * 从指定的的元素集中随机一个元素
   *
   * @param collection 元素集
   */
  public static <T> T randomElement(Collection<T> collection) {
    if (collection == null || collection.isEmpty()) {
      throw new IllegalArgumentException("元素集不能为空！");
    }
    int index = random(0, collection.size() - 1);
    Iterator<T> it = collection.iterator();
    for (int i = 0; i <= index && it.hasNext(); i++) {
      T t = it.next();
      if (i == index) {
        return t;
      }
    }
    return null;
  }


  /**
   * 生成随机数字
   */
  public static String randomDigit(int length) {
    if (length < 1) {
      throw new IllegalArgumentException("非法的长度:" + length);
    }
    RandomStringGenerator randomStringGenerator = new RandomStringGenerator.Builder()
        .withinRange('0', '9').build();
    return randomStringGenerator.generate(length);
  }

  /**
   * 生成随机数
   *
   * @return String    返回类型
   */
  public static String randomPwd(int count) {
    RandomStringGenerator randomStringGenerator = new RandomStringGenerator.Builder()
        .withinRange('0', 'z').build();
    return randomStringGenerator.generate(count);
  }

  /**
   * 获取一定长度的随机字符串
   *
   * @param length 指定字符串长度
   * @return 一定长度的字符串
   */
  public static String randomString(int length) {
    String base = "abcdefghijklmnopqrstuvwxyz0123456789";
    Random random = new Random();
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < length; i++) {
      int number = random.nextInt(base.length());
      sb.append(base.charAt(number));
    }
    return sb.toString();
  }

  /**
   * 生成随机数
   *
   * @return String    返回类型
   */
  public static String randomPwd() {
    return randomPwd(10);
  }

  /**
   * 从指定的元素数组中随机出一个元素
   *
   * @param array 元素数组
   */
  public static <T> T randomElement(T[] array) {
    if (array == null || array.length == 0) {
      throw new IllegalArgumentException("元素数组不能为空！");
    }
    return randomElement(Arrays.asList(array));
  }

  /**
   * 根据每个几率返回随机的一个索引
   *
   * @return -1失败or随机的索引
   */
  public static int randomIndexByProb(List<Integer> probs) {
    LinkedList<Integer> newProbs = new LinkedList<Integer>();
    int lastTotalProb = 0;
    for (Integer prob : probs) {
      int cuttentTotalProb = lastTotalProb + prob;
      newProbs.add(cuttentTotalProb);
      lastTotalProb = cuttentTotalProb;
    }
    if (newProbs.isEmpty()) {
      return -1;
    }
    int totalProb = newProbs.getLast();

    // 总概率为0
    if (totalProb == 0) {
      return -1;
    }
    int random = random(0, totalProb - 1);
    for (int i = 0; i < newProbs.size(); i++) {
      int cuttentTotalProb = newProbs.get(i);
      if (cuttentTotalProb > random) {
        return i;
      }
    }
    return -1;
  }

  /**
   * 根据每个几率返回随机的一个索引
   *
   * @return -1失败or随机的索引
   */
  public static int randomIndexByProb(int[] array) {
    if (array == null || array.length == 0) {
      throw new IllegalArgumentException("元素数组不能为空！");
    }
    List<Integer> list;
    list = new ArrayList<>();
    for (int i : array) {
      list.add(i);
    }
    return randomIndexByProb(list);
  }

  /**
   * 生成盐值
   */
  public static String createSalt() {
    return randomPwd(10);
  }


  /**
   * 生成盐值
   */
  public static String createSalt(int count) {
    return randomPwd(count);
  }

  public static void main(String[] args) {
//        String salt = createSalt();
    System.out.println(randomString(6));
//        System.out.println(Md5Utils.encode("xiaomo",salt));
  }
}
